package grabana

import (
	
	
	
	
	
	

	
	
	
)

// ErrAlertNotFound is returned when the requested alert can not be found.
var ErrAlertNotFound = errors.New("alert not found")

type alertRef struct {
	Namespace string
	RuleGroup string
}

// ConfigureAlertManager updates the alert manager configuration.
func ( *Client) ( context.Context,  *alertmanager.Manager) error {
	,  := .MarshalIndentJSON()
	if  != nil {
		return 
	}

	,  := .sendJSON(, http.MethodPost, "/api/alertmanager/grafana/config/api/v1/alerts", )
	if  != nil {
		return 
	}

	defer func() { _ = .Body.Close() }()

	if .StatusCode != http.StatusAccepted {
		return .httpError()
	}

	return nil
}

// AddAlert creates an alert group within a given namespace.
func ( *Client) ( context.Context,  string,  alert.Alert,  map[string]string) error {
	// Find out which datasource the alert depends on, and inject its UID into the sdk definition
	 := defaultDatasourceKey
	if .Datasource != "" {
		 = .Datasource
	}

	 := []
	if  == "" {
		return fmt.Errorf("could not infer datasource UID from its name: %s", )
	}

	.HookDatasourceUID()

	// Before we can add this alert, we need to delete any other alert that might exist for this dashboard and panel
	if  := .DeleteAlertGroup(, , .Builder.Name);  != nil && !errors.Is(, ErrAlertNotFound) {
		return fmt.Errorf("could not delete existing alerts: %w", )
	}

	,  := json.Marshal(.Builder)
	if  != nil {
		return 
	}

	// Save the alert!
	,  := .sendJSON(, http.MethodPost, "/api/ruler/grafana/api/v1/rules/"+url.PathEscape(), )
	if  != nil {
		return 
	}

	defer func() { _ = .Body.Close() }()

	if .StatusCode != http.StatusAccepted {
		return .httpError()
	}

	return nil
}

// DeleteAlertGroup deletes an alert group.
func ( *Client) ( context.Context,  string,  string) error {
	 := fmt.Sprintf("/api/ruler/grafana/api/v1/rules/%s/%s", url.PathEscape(), url.PathEscape())
	,  := .delete(, )
	if  != nil {
		return 
	}

	defer func() { _ = .Body.Close() }()

	if .StatusCode == http.StatusNotFound {
		return ErrAlertNotFound
	}
	if .StatusCode != http.StatusAccepted {
		return .httpError()
	}

	return nil
}

// listAlertsForDashboard fetches a list of alerts linked to the given dashboard.
func ( *Client) ( context.Context,  string) ([]alertRef, error) {
	,  := .get(, "/api/ruler/grafana/api/v1/rules?dashboard_uid="+url.QueryEscape())
	if  != nil {
		return nil, 
	}

	defer func() { _ = .Body.Close() }()

	if .StatusCode != http.StatusOK {
		return nil, .httpError()
	}

	var  map[string][]sdk.Alert
	if  := decodeJSON(.Body, &);  != nil {
		return nil, 
	}

	var  []alertRef

	for  := range  {
		for ,  := range [] {
			 = append(, alertRef{
				Namespace: ,
				RuleGroup: .Name,
			})
		}
	}

	return , nil
}